package com.zbkj.service.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zbkj.dal.base.constants.ProductConstants;
import com.zbkj.dal.base.enums.BizTypeEnum;
import com.zbkj.dal.base.enums.RecyclePositionEnums;
import com.zbkj.dal.common.exception.CrmebException;
import com.zbkj.dal.entity.ba.BizImg;
import com.zbkj.dal.entity.ba.Recycle;
import com.zbkj.dal.entity.product.Product;
import com.zbkj.dal.entity.product.ProductAttr;
import com.zbkj.dal.entity.product.ProductAttrValue;
import com.zbkj.dal.entity.product.ProductDescription;
import com.zbkj.dal.pojo.request.PageParamRequest;
import com.zbkj.dal.pojo.request.ba.ConcludeRecycleRequest;
import com.zbkj.dal.pojo.request.ba.RecycleQueryRequest;
import com.zbkj.dal.pojo.request.ba.RecycleRequest;
import com.zbkj.dal.pojo.response.ba.MyRecycleResponse;
import com.zbkj.dal.pojo.response.ba.RecycleDetailResponse;
import com.zbkj.dal.pojo.response.ba.RecycleResponse;
import com.zbkj.dal.dao.RecycleMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zbkj.service.service.*;
import com.zbkj.service.util.UserUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 回收寄卖 服务实现类
 * </p>
 *
 * @author jhui
 * @since 2023-10-03
 */
@Service
public class RecycleServiceImpl extends ServiceImpl<RecycleMapper, Recycle> implements RecycleService {

    @Autowired
    private UserService userService;
    @Autowired
    private BizImgService bizImgService;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private SystemAttachmentService systemAttachmentService;
    @Autowired
    private ProductService productService;
    @Autowired
    private ProductAttrService attrService;
    @Autowired
    private ProductAttrValueService productAttrValueService;
    @Autowired
    private ProductDescriptionService productDescriptionService;

    @Resource
    private AliSmsServiceImpl aliSmsService;

    @Override
    public List<MyRecycleResponse> listMyRecycle(Integer status, PageParamRequest pageParamRequest) {
        List<MyRecycleResponse> result = Lists.newArrayList();
        Integer userId = userService.getUserIdException();
        LambdaQueryWrapper<Recycle> queryWrapper = Wrappers.lambdaQuery(Recycle.class);
        queryWrapper.eq(Recycle::getUid, userId);
        if (status != null && status != -1) {
            queryWrapper.eq(Recycle::getStatus, status);
        }
        queryWrapper.orderByDesc(Recycle::getId);
        queryWrapper.last("LIMIT " + (pageParamRequest.getPage() - 1) * pageParamRequest.getLimit() + "," + pageParamRequest.getLimit());
        List<Recycle> list = list(queryWrapper);

        if (CollUtil.isEmpty(list)) {
            return result;
        }
        List<BizImg> bizImgs = Lists.newArrayList();
        List<Integer> ids = list.stream().map(m -> m.getId()).distinct().collect(Collectors.toList());
        if (CollUtil.isNotEmpty(ids)) {
            bizImgs = bizImgService.listByBizIds(BizTypeEnum.RECYCLE.getType(), ids);
        }
        for (Recycle share : list) {
            MyRecycleResponse myShareResponse = new MyRecycleResponse();
            BeanUtils.copyProperties(share, myShareResponse);
            List<String> paths = bizImgs.stream().filter(p -> ObjectUtils.nullSafeEquals(p.getBizId(), share.getId())
                            && StringUtils.isNotBlank(p.getPath())).map(m -> m.getPath())
                    .collect(Collectors.toList());
            myShareResponse.setPics(paths);
            result.add(myShareResponse);
        }

        return result;
    }

    @Override
    public Boolean deleteMyRecycle(Integer id) {
        Integer userId = userService.getUserIdException();
        LambdaQueryWrapper<Recycle> queryWrapper = Wrappers.lambdaQuery(Recycle.class);
        queryWrapper.eq(Recycle::getId, id).eq(Recycle::getStatus, 0).eq(Recycle::getUid, userId);
        return this.remove(queryWrapper);
    }

    @Override
    public Boolean create(RecycleRequest recycleRequest) {
        Integer userId = userService.getUserIdException();
        Recycle recycle = new Recycle();
        BeanUtils.copyProperties(recycleRequest, recycle);
        recycle.setProductId(null);
        recycle.setEstimatePrice(null);
        recycle.setUid(userId);
        recycle.setStatus(0);
        recycle.setCreateTime(LocalDateTime.now());
        recycle.setUpdateTime(LocalDateTime.now());

        //            bizImgService.deleteByBizId(BizTypeEnum.SHARE.getType(),)

        return Boolean.TRUE.equals(transactionTemplate.execute((e) -> {
//            bizImgService.deleteByBizId(BizTypeEnum.SHARE.getType(),)
            save(recycle);
            if (CollUtil.isNotEmpty(recycleRequest.getPics())) {
                recycleRequest.getPics().forEach(c -> {
                    c.setBizId(recycle.getId());
                    c.setCreateTime(LocalDateTime.now());
                    c.setUpdateTime(LocalDateTime.now());
                    c.setType(BizTypeEnum.RECYCLE.getType());
                    c.setPath(systemAttachmentService.clearPrefix(c.getPath()));
                });

                bizImgService.saveBatch(recycleRequest.getPics());

                //发送短息
                aliSmsService.sendServiceMsg("回收寄卖");
            }
            return Boolean.TRUE;
        }));
    }

    @Override
    public PageInfo<RecycleResponse> queryRecyclePaged(RecycleQueryRequest recycleQueryRequest, PageParamRequest pageParamRequest) {
        LambdaQueryWrapper<Recycle> queryWrapper = Wrappers.lambdaQuery(Recycle.class);
        if (recycleQueryRequest.getStatus() != null) {
            queryWrapper.eq(Recycle::getStatus, recycleQueryRequest.getStatus());
        }
        if (recycleQueryRequest.getBeginDate() != null) {
            queryWrapper.ge(Recycle::getCreateTime, recycleQueryRequest.getBeginDate());
        }
        if (recycleQueryRequest.getEndDate() != null) {
            queryWrapper.lt(Recycle::getCreateTime, recycleQueryRequest.getEndDate().plusDays(1));
        }
        queryWrapper.orderByDesc(Recycle::getId);
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<Recycle> list = this.list(queryWrapper);
        PageInfo<Recycle> pageInfo = PageInfo.of(list);

        PageInfo<RecycleResponse> result = new PageInfo<>();
        result.setTotal(pageInfo.getTotal());
        List<RecycleResponse> dtos = Lists.newArrayList();
        for (Recycle share : pageInfo.getList()) {
            RecycleResponse recycleResponse = new RecycleResponse();
            BeanUtils.copyProperties(share, recycleResponse);
            dtos.add(recycleResponse);
        }
        result.setList(dtos);
        UserUtils.fillUsers(dtos);
        return result;
    }

    @Override
    public boolean createProduct(Integer id) {
        Recycle recycle = this.getById(id);
        // product部分
        Product product = new Product();
        product.setId(null);
        product.setMerId(3);
        product.setPrice(recycle.getEstimatePrice());
        product.setOtPrice(recycle.getEstimatePrice());
        product.setCost(recycle.getEstimatePrice());
        product.setStock(1);
        product.setRentPrice(recycle.getEstimatePrice());
        product.setOwnerUid(recycle.getUid());

        product.setAuditStatus(ProductConstants.AUDIT_STATUS_EXEMPTION);
        product.setIsAudit(false);
        product.setIsShow(false);

        // 轮播图片
        List<String> slideImgs = Lists.newArrayList();
        List<BizImg> bizImgs = bizImgService.listByBizId(BizTypeEnum.RECYCLE.getType(), id);
        if (CollectionUtils.isNotEmpty(bizImgs)) {
            product.setImage(bizImgs.get(0).getPath());
            for (BizImg bizImg : bizImgs) {
                slideImgs.add(bizImg.getPath());
            }
        } else {
            slideImgs.add("");
        }
        product.setSliderImage(JSON.toJSONString(slideImgs));


        // attr部分
        List<ProductAttr> attrAddList = CollUtil.newArrayList();

        ProductAttr attr = new ProductAttr();
        attr.setAttrName(ProductConstants.SINGLE_ATTR_NAME);
        attr.setType(ProductConstants.PRODUCT_TYPE_NORMAL);
        attr.setAttrValues(ProductConstants.PRODUCT_TYPE_NORMAL_STR);
        attr.setIsDel(false);
        attrAddList.add(attr);


        // attrValue部分
        List<ProductAttrValue> attrValueAddList = CollUtil.newArrayList();
        ProductAttrValue attrValue = new ProductAttrValue();

        attrValue.setId(null);
        attrValue.setSku((ProductConstants.PRODUCT_TYPE_NORMAL_STR));
        attrValue.setStock(1);
        attrValue.setSales(0);
        attrValue.setPrice(product.getPrice());
//        attrValue.setImage(systemAttachmentService.clearPrefix(e.getImage(), cdnUrl));
        attrValue.setCost(product.getCost());
        attrValue.setOtPrice(product.getOtPrice());
        attrValue.setWeight(BigDecimal.ZERO);
        attrValue.setVolume(BigDecimal.ZERO);
        attrValue.setBrokerage(0);
        attrValue.setBrokerageTwo(0);
        attrValue.setVersion(0);
        attrValue.setProductId(product.getId());
        attrValue.setQuota(0);
        attrValue.setQuotaShow(0);
        attrValue.setType(ProductConstants.PRODUCT_TYPE_NORMAL);
        HashMap<Object, Object> valueAddMap = Maps.newHashMap();
        valueAddMap.put(ProductConstants.SINGLE_ATTR_NAME, ProductConstants.PRODUCT_TYPE_NORMAL_STR);
        attrValue.setAttrValue(JSON.toJSONString(valueAddMap));
        attrValueAddList.add(attrValue);
        // 处理富文本
        ProductDescription spd = new ProductDescription();
        spd.setDescription("");
        spd.setType(ProductConstants.PRODUCT_TYPE_NORMAL);

        Boolean execute = transactionTemplate.execute(e -> {
            productService.save(product);

            if (CollUtil.isNotEmpty(attrAddList)) {
                attrAddList.forEach(item -> item.setProductId(product.getId()));
                attrService.saveBatch(attrAddList);
            }
            if (CollUtil.isNotEmpty(attrValueAddList)) {
                attrValueAddList.forEach(item -> item.setProductId(product.getId()));
                productAttrValueService.saveBatch(attrValueAddList);
            }

            spd.setProductId(product.getId());
            productDescriptionService.deleteByProductId(product.getId(), ProductConstants.PRODUCT_TYPE_NORMAL);
            productDescriptionService.save(spd);

            recycle.setProductId(product.getId());
            this.modifyRecycleProduct(recycle);
            return Boolean.TRUE;
        });
        return execute;
    }

    @Override
    public RecycleDetailResponse detail(Integer id) {
        Recycle recycle = this.getById(id);
        RecycleDetailResponse shareDetailResponse = new RecycleDetailResponse();
        BeanUtils.copyProperties(recycle, shareDetailResponse);

        List<BizImg> bizImgs = bizImgService.listByBizId(BizTypeEnum.RECYCLE.getType(), id);
        shareDetailResponse.setPics(bizImgs);
        return shareDetailResponse;
    }

    @Override
    public boolean conclude(ConcludeRecycleRequest concludeRecycleRequest) {
        LambdaUpdateWrapper<Recycle> updateWrapper = Wrappers.lambdaUpdate(Recycle.class);
        updateWrapper
                .set(Recycle::getCode, concludeRecycleRequest.getCode())
                .set(Recycle::getEstimatePrice, concludeRecycleRequest.getEstimatePrice())
                .set(Recycle::getStatus, concludeRecycleRequest.getStatus())
                .set(Recycle::getRemark, concludeRecycleRequest.getRemark())
                .set(Recycle::getOperatorId, concludeRecycleRequest.getOperatorId())
                .set(Recycle::getUpdateTime, LocalDateTime.now())
                .eq(Recycle::getId, concludeRecycleRequest.getId());
        boolean result = this.update(updateWrapper);
        return result;
    }


    private void modifyRecycleProduct(Recycle recycle) {
        LambdaUpdateWrapper<Recycle> updateWrapper = Wrappers.lambdaUpdate(Recycle.class);
        updateWrapper.set(Recycle::getProductId, recycle.getProductId())
                .eq(Recycle::getId, recycle.getId());
        update(updateWrapper);
    }
}
